#include "widget.h"
#include <QDebug>
#include <QDir>
#include <QPainter>
#include <QTime>
#include <QDialog>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setMinimumSize(800, 600);
    this->setWindowTitle("HelloMaze");
    //初始化迷宫
    drawStatus = 0;
    helloMaze = NULL;
    savePic = false;
    showSolution = false;
    blockSize = 10;
    blockInteval = 3;
    blockColor = "white";
    wallColor = "black";
    mazeImage = NULL;
    solutionImage = NULL;
    newMaze(10);

    picLabel = new QLabel;
    picLabel->setText("Author:\n"
                      "\tCharles in UESTC\n"
                      "Usage:\n"
                      "\tUpdate--刷新迷宫\n"
                      "\tSave----保存迷宫\n"
                      "\tSolve---显示解决路径\n"
                      "\t下面图标--程序源码链接\n"
                      "Tips:\n"
                      "\t300x300迷宫耗时5s"
                      "\t500x500迷宫耗时0.5min\n"
                      "\t优化不下去了T_T");
    picArea = new QScrollArea();
    picArea->resize(600, 600);
    picArea->setWidget(picLabel);

    //以下是右边区域的控件与布局
    sizeCombo = new QComboBox();
    for (int i = 10 ; i <= 500 ; i++)
        sizeCombo->addItem(QString::number(i));
    connect(sizeCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeMaze(QString)));

    solveBtn = new QPushButton("Solve it!");
    saveBtn = new QPushButton("Save");
    updateBtn = new QPushButton("Update");
    updateBtn->setToolTip("Generate a new maze of the same size");
    giteeBtn = new QPushButton;
    giteeBtn->setIcon(QIcon(":/gitee/gitee.jpg"));
    giteeBtn->setIconSize(QSize(65, 65));
    giteeBtn->setMaximumSize(70, 70);
    giteeBtn->setToolTip("View Code On Gitee.com");

    connect(saveBtn, SIGNAL(clicked(bool)), this, SLOT(saveBtnClicked()));
    connect(solveBtn, SIGNAL(clicked(bool)), this, SLOT(drawPath()));
    connect(updateBtn, SIGNAL(clicked(bool)), this, SLOT(updateMaze()));
    connect(giteeBtn, SIGNAL(clicked(bool)), this, SLOT(giteeBtnClicked()));

    msgBrowser = new QTextBrowser;
    msgBrowser->setFrameStyle(QFrame::Sunken | QFrame::Panel);
    msgBrowser->setText("HelloMaze!");
    QPalette *p = new QPalette();
    *p = msgBrowser->palette();
    p->setBrush(QPalette::Base, QBrush(Qt::NoBrush));
    msgBrowser->setPalette(*p);
    rightLayout = new QGridLayout();



    rightLayout->addWidget(msgBrowser, 0, 0, 1, 2, Qt::AlignCenter);
    rightLayout->addWidget(sizeCombo, 1, 0, 1, 1);
    rightLayout->addWidget(solveBtn, 1, 1, 1, 1);
    rightLayout->addWidget(updateBtn, 2, 0, 1, 1);
    rightLayout->addWidget(saveBtn, 2, 1, 1, 1);
    rightLayout->addWidget(giteeBtn, 3, 0, 1, 2, Qt::AlignCenter);
    QSpacerItem *spacer = new QSpacerItem(50, 50, QSizePolicy::Maximum);
    rightLayout->addItem(spacer, 4, 0);

    rightLayout->setRowStretch(0, 3);
    rightLayout->setRowStretch(1, 1);
    rightLayout->setRowStretch(2, 1);
    rightLayout->setRowStretch(3, 10);
    rightLayout->setSpacing(5);
    rightLayout->setMargin(5);


    mainLayout = new QHBoxLayout(this);
    mainLayout->addWidget(picArea);
    mainLayout->setStretch(0, 8);
    mainLayout->addLayout(rightLayout);
    mainLayout->setStretch(1, 2);

    clipBoard = QApplication::clipboard();
}


void Widget::updateMaze()
{
    changeMaze(QString::number(mazeSize));
    msgBrowser->setText("Maze updated");
}

//绘制迷宫
void Widget::drawMaze()
{
    iWantToPaint = true;
    drawStatus |= DRAW_MAZE;
    drawStatus &= ~(MAZE_DRAWN);
    this->paintEvent();
    msgBrowser->setText("Maze displayed");
}

//绘制路线
void Widget::drawPath()
{
    iWantToPaint = true;
    drawStatus |= DRAW_SOLUTION;
    drawStatus &= ~(SOLUTION_DRAWN);
    this->paintEvent();
    msgBrowser->setText("Solution displayed\n");
}

void Widget::newMaze(int s=20)
{
    delete helloMaze;
    helloMaze = new Maze(s);
    helloMaze->solve();
    delete mazeImage;
    delete solutionImage;
    drawStatus = 0;
    mazeImage = NULL;
    solutionImage = NULL;
    mazeSize = helloMaze->getSize();
    mazeWidth = mazeSize*blockSize + blockInteval*(mazeSize+1);
    mazeHeight = mazeWidth;
}

void Widget::changeMaze(QString s)
{
    iWantToPaint = true;
    newMaze(s.toInt());
    drawStatus |= DRAW_MAZE;
    drawStatus &= ~(MAZE_DRAWN);
    paintEvent();
    msgBrowser->setText("Maze changed");
}

void Widget::saveBtnClicked()
{
    if (!(mazeImage || solutionImage))
    {
        saveBox = new QMessageBox(this);
        saveBox->setText("无法保存，尚未生成图片!");
        saveBox->show();
        return;
    }
    saveBox = new QMessageBox(this);
    saveBox->setText("保存中...");
    saveBox->show();
    QString result;
    QString mazeName = "maze"+QString::number(mazeSize)+".jpg";
    QString solutionName = "solution" + QString::number(mazeSize) + ".jpg";
    if (mazeImage)
    {
        mazeImage->save(mazeName, "JPEG");
        result = mazeName + "\n";
    }
    if (solutionImage)
    {
        solutionImage->save(solutionName, "JPEG");
        result += solutionName;
    }

    saveBox->setText("以下已保存在当前目录\n" + result);
    saveBox->show();

}

void Widget::giteeBtnClicked()
{
    msgBrowser->setText("源码URL已复制到系统剪贴板!请到浏览器访问.");
    clipBoard->setText("https://gitee.com/Charles-Neil/HelloMaze");
}

void Widget::paintEvent()
{
    //如果没画过图
    if (iWantToPaint)
    {
        int ox = 10, oy = 10;
        //如果没有画过这个迷宫，且命令是画迷宫
        if (!(drawStatus & MAZE_DRAWN) && (drawStatus & DRAW_MAZE))
        {
            //newImage用于暂存图片，最后存入mazeImage,和solutionImage
            QImage *newImage = new QImage(mazeWidth+20, mazeHeight+20, QImage::Format_ARGB32);
            newImage->fill("white");
            QPainter painter;

            painter.begin(newImage);
            painter.setPen(Qt::black);
            vector<int> v(mazeSize*mazeSize);
            v = helloMaze->getMaze();
            for (int i = 0 ; i < mazeSize +1 ; i++)
            {
                //竖
                painter.fillRect(i*(blockInteval+blockSize)+ox, oy, blockInteval, mazeHeight, Qt::black);
                //横
                painter.fillRect(ox, i*(blockInteval+blockSize)+oy, mazeWidth, blockInteval, Qt::black);
            }
            for (int i = 0 ; i < v.size() ; i++)
            {
                //求得每个block的左上角坐标
                int bx = ox+blockInteval+(i%mazeSize)*(blockInteval+blockSize);
                int by = oy+blockInteval + (i/mazeSize)*(blockInteval+blockSize);
                //上方通
                if (!(v[i] & UP))
                    painter.fillRect(bx, by-blockInteval, blockSize, blockInteval, blockColor);
                if (!(v[i] & DOWN))
                    painter.fillRect(bx, by+blockSize, blockSize, blockInteval, blockColor);
                if (!(v[i] & RIGHT))
                    painter.fillRect(bx+blockSize, by, blockInteval, blockSize, blockColor);
                if (!(v[i] & LEFT))
                    painter.fillRect(bx-blockInteval, by, blockInteval, blockSize, blockColor);
            }
            mazeImage = new QImage(*newImage);
            QLabel *tobedeleted = picLabel;
            tobedeleted->deleteLater();
            picLabel = new QLabel;
            picLabel->setPixmap(QPixmap::fromImage(*mazeImage));
            picArea->setWidget(picLabel);
            drawStatus |= MAZE_DRAWN;
            drawStatus &= ~(DRAW_MAZE);
            painter.end();
            delete newImage;
        }
        //没画过ｓｏｌｕｔｉｏｎ，现在要画
        if (!(drawStatus & SOLUTION_DRAWN) && (drawStatus & DRAW_SOLUTION))
        {
            QImage *newImage = new QImage(*mazeImage);
            QPainter painter;
            painter.begin(newImage);
            vector<int> p = helloMaze->getPath();
            for (int i = 0 ; i < p.size() ; i++)
            {
                //求每个block中心坐标
                int cx = ox+blockInteval+(p[i]%mazeSize)*(blockInteval+blockSize)+2;
                int cy = oy+blockInteval + (p[i]/mazeSize)*(blockInteval+blockSize)+2;
                painter.fillRect(cx, cy, blockSize-4, blockSize-4, Qt::blue);
            }
            solutionImage = new QImage(*newImage);
            picLabel->setPixmap(QPixmap::fromImage(*solutionImage));
            ("solution" + QString::number(mazeSize) + ".jpg", "JPEG");
            drawStatus |= SOLUTION_DRAWN;
            drawStatus &= ~(DRAW_SOLUTION);
            painter.end();
            delete newImage;
        }

        iWantToPaint = false;
    }
}

Widget::~Widget()
{

}
